using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Reflection;

using Android.App;
using Android.Content;
using Android.OS;
using Android.Runtime;
using Android.Views;
using Android.Widget;
using FunctionInterface;

namespace FunctionInterface
{
	public class CommandDispatcher 
	{
		public event OutputMessageEventHandler OutputMessage;
		public event ProcessChangedEvnetHandler ProcessChanged;
		
		public IProcessCommand CurProcess {get; set;}
		
		protected List<CommandConfig> Commands {get; set;}
		
		private Context MainAppContext = null;

		public CommandDispatcher(Context c)
		{
			MainAppContext = c;
			// 查找配置文件
			Commands = new List<CommandConfig>();
			Commands.Add(new CommandConfig()
			            { AssemblyName = "Functions",
						  ClassName = "Functions.SearchContact",
				         CommandName = "search",
				        Command = "sc",
						Details = "查找联系人"
			});
			Commands.Add(new CommandConfig()
			            { AssemblyName = "Functions",
						  ClassName = "Functions.Dial",
				         CommandName = "dial",
				        Command = "d",
				        Details = "拨打电话 "
			});
			Commands.Add(new CommandConfig()
			            { AssemblyName = "Functions",
						  ClassName = "Functions.SendMessage",
				         CommandName = "SendMessage",
				        Command = "send",
				        Details = "发送信息"
			});
			Commands.Add(new CommandConfig()
			            { AssemblyName = "Functions",
						  ClassName = "Functions.Net.LinkSpecialNet",
				         CommandName = "LinkSpecialNet",
				        Command = "link",
				        Details = "连接查询网"
			});
		}
		
		/// <summary>
		/// Process the specified command.
		/// </summary>
		/// <param name='command'>
		/// Command.
		/// </param>
		public void Process (string command)
		{
			// 切换命令后，直接由当前处理程序处理该输入
			if(CurProcess != null)
			{
				CurProcess.Process(command);
				return;
			}
					
			// 直接调用命令处理后返回(输入类似“net -s -t”)
			if(command.Trim().Contains(" "))
			{
				string cms = command.Split(' ')[0];
				foreach(CommandConfig item in Commands)
				{
					if(cms == item.Command)
					{
						IProcessCommand p = CreateProcess(item.AssemblyName, item.ClassName);
						p.Process(command.Trim ());
					}
				}
			}
			
			// 切换命令（输入类似“net”）
			foreach(CommandConfig item in Commands)
			{
				if(command.Trim() == item.Command)
				{
					CurProcess = CreateProcess(item.AssemblyName, item.ClassName);
					ProcessChanged(this, new ProcessChangedEvnetArgs() { CurProcessCommand = CurProcess});
				}
			}
		}
		
		/// <summary>
		/// Validate the specified command.
		/// </summary>
		/// <param name='command'>
		/// If set to <c>true</c> command.
		/// </param>
		public bool Validate (string command)
		{
			return true;
		}
		
		/// <summary>
		/// Gets the command list.
		/// </summary>
		/// <returns>
		/// The command list.
		/// </returns>
		public IEnumerator<string> GetProcessCommands ()
		{
			foreach(CommandConfig config in Commands)
			{
				yield return string.Format(" ●{0} {1}", config.Command, config.Details);
			}
		}
		
		/// <summary>
		/// Creates the process.
		/// </summary>
		/// <returns>
		/// The process.
		/// </returns>
		/// <param name='assemblyName'>
		/// Assembly name.
		/// </param>
		/// <param name='className'>
		/// Class name.
		/// </param>
		protected IProcessCommand CreateProcess(string assemblyName, string className)
		{
			Assembly assembly = Assembly.Load(assemblyName);
			IProcessCommand command = assembly.CreateInstance(className) as IProcessCommand;
			command.Context = MainAppContext;
			command.OutputMessage += (sender, e) => 
			{
				if(OutputMessage != null)
				{
					OutputMessage(this, e);
				}
			};
			return command;
		}
	}
}

